package com.zjsru.leetcode75.level1;

import java.util.Collections;
import java.util.LinkedList;

/**
 * @Author: cookLee
 * @Date: 2023-11-05
 * 字符串解码
 */
public class DecodeString {
    /**
     * 主
     * 解码字符串
     * \
     * 输入：s = "3[a]2[bc]"
     * 输出："aaabcbc"
     * \
     * 输入：s = "3[a2[c]]"
     * 输出："accaccacc"
     * \
     * 输入：s = "2[abc]3[cd]ef"
     * 输出："abcabccdcdcdef"
     * \
     * @param args args
     */
    public static void main(String[] args) {
        DecodeString decodeString = new DecodeString();
        String s = "3[a]2[bc]";
        System.out.println(decodeString.decodeString(s));
    }

    /**
     * 位置
     */
    private Integer position;

    /**
     * 左括号
     */
    private final static Character CHARACTER_LEFT_BUCKET = '[';

    /**
     * 右括号
     */
    private final static String STRING_RIGHT_BUCKET = "[";

    /**
     * 解码字符串:模拟栈
     *
     * @param s s
     * @return {@link String}
     */
    public String decodeString(String s) {
        LinkedList<String> linkedList = new LinkedList<String>();
        position = 0;
        while (position < s.length()) {
            //判断是否是数字
            if (Character.isDigit(s.charAt(position))) {
                // 获取一个数字并进栈
                String digits = this.digitHelper(s);
                linkedList.addLast(digits);
            } else if (Character.isLetter(s.charAt(position)) || s.charAt(position) == CHARACTER_LEFT_BUCKET) {
                //判断字母，并且由左括号开始统计
                String letters = String.valueOf(s.charAt(position));
                linkedList.addLast(letters);
                position++;
            } else {
                //此位置加一 即跳过“]"符号
                position++;
                LinkedList<String> link = new LinkedList<>();
                while (!STRING_RIGHT_BUCKET.equals(linkedList.peekLast())) {
                    link.addLast(linkedList.removeLast());
                }
                //倒转排序
                Collections.reverse(link);
                // 左括号出栈
                linkedList.removeLast();
                // 此时栈顶为当前应该出现的次数，其他数据已经被弹出
                int repeat = Integer.parseInt(linkedList.removeLast());
                String linkString = this.helper(link);
                StringBuilder sb = new StringBuilder();
                while (repeat > 0) {
                    sb.append(linkString);
                    repeat--;
                }
                // 将构造好的字符串入栈
                linkedList.addLast(sb.toString());
            }

        }
        return this.helper(linkedList);
    }

    /**
     * 数字助手:获取到字母或者括号前的所有数字
     *
     * @param s s
     * @return {@link String}
     */
    private String digitHelper(String s) {
        StringBuilder sb = new StringBuilder();
        while(Character.isDigit(s.charAt(position))){
            sb.append(s.charAt(position));
            position++;
        }
        return sb.toString();
    }

    /**
     * 帮手
     * 转化字符串助手类
     *
     * @param link 链接
     * @return {@link String}
     */
    public String helper(LinkedList<String> link) {
        StringBuilder sb = new StringBuilder();
        for (String s : link) {
            sb.append(s);
        }
        return sb.toString();
    }


}
